package simonxianyu.boot.mybatis.base;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;

/**
 * 提供MyBatis数据库访问service的基类，实现了一些常用方法。
 *
 * @param <M> Mapper接口类，声明后可实现自动注入
 * @param <T> 数据类
 * @param <ID> 主键类
 */
abstract public class BaseMyBatisService<M extends BaseMapper<T,ID>,T,ID> {
  @Autowired
  protected M mapper;

  public List<T> findAll() {
    return mapper.findAll();
  }

  public List<T> findByExample(T e) {
    if (null != e) {
      return mapper.findByExample(e);
    }
    return Collections.emptyList();
  }

  public T get(ID id) {
    return mapper.get(id);
  }

  @Transactional
  public void deleteById(ID id) {
    if (null != id) {
      mapper.deleteById(id);
    }
  }

  /** 默认的保存 方法*/
  @Transactional
  @SuppressWarnings("unchecked")
  public ID saveNew(T m) {
    mapper.saveNew(m);
    if (m instanceof IdEntity) {
      return (ID) ((IdEntity) m).extractId();
    }
    return null;
  }

  /**
   * 更新指定对象，需要调用者确保字段都正确合并了，否则的话应当使用如下形式：
   *<pre>@Transactional
   *   public Long saveOrUpdate(Role n) {
   *     Role e;
   *     Date now = new Date();
   *     if (n.getId() == null) {
   *       e = n;
   *       saveNew(e, now);
   *     } else {
   *       e = mapper.get(n.getId());
   *       if (null == e) {
   *         e = n;
   *         saveNew(e, now);
   *       } else {
   *         e.mergeNew(n);
   *         e.setUpdatedAt(now);
   *         mapper.update(e);
   *       }
   *     }
   *     return e.getId();
   *   }</pre>
   */
  @Transactional
  public void update(T m) {
    mapper.update(m);
  }

  public Long count() {
    return mapper.count();
  }

  public Long countByExample(T e) {
    return mapper.countByExample(e);
  }
}
